#ifndef H_LOGGER
#define H_LOGGER

#include <stdio.h>
#include <vector>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

//if fd_ == -1 means that we didn't open logger.txt 
class buffer {
    public:
        buffer() {
            fd_ = -1;
        }
        
        ~buffer() {
            if(fd_ != -1) {
                this->Flush();
                if(close(fd_) == -1) {}
            }
        }
        
        bool initialize(const char* file_name) {
            if(fd_ != -1) return false;
            fd_ = open(file_name, O_RDWR|O_CREAT|O_TRUNC, 0666);
            if(fd_ == -1) {
                std::cout << "I can't create logger file \n";
                return false;
            }
            return true;           
        }
        
        void Write(const char* str) {
            std::string temp(str);
            buf_.push_back(temp);
            if(buf_.size() > size_of_buf_fer_) this->Flush();
        }

        void Flush() {
            if(fd_ == -1) return;
            for(int i = 0; i < buf_.size(); i++) {
                write(fd_, buf_[i].c_str(), buf_[i].size());
            }
            buf_.clear();
        }
    private:
        static const int size_of_buf_fer_ = 10;
        int fd_;
        std::vector<std::string> buf_;
        
       
                  
};

class Logger {
    public:
        enum Level {
            ERROR = 0,
            WARNING = 1
        };
        static Logger& Instance() {
            static Logger logger;
            return logger;
        }        
        bool Initialize(const char* file_name) {
            return buf_.initialize(file_name);     
        }
    
        void Log(Level level,const char* str) {
            std::string message(str);
            //In future(while debagging write warning)
            if(level == ERROR) {
                message += "\n";
                buf_.Write(message.c_str());                
            }
            
        }

    private:
        Logger() {
        }        
        
        Logger(const Logger& root) {}

        Logger& operator=(const Logger&) {}

        ~Logger() {
        }
        
        buffer buf_;
};

void LogEr(const char* str) {
     Logger::Instance().Log(Logger::ERROR, str);
}

void LogWar(const char* str) {
    Logger::Instance().Log(Logger::WARNING, str);
}

#endif

